﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Surface.Core;
using Microsoft.Surface.Core.Manipulations;
using Microsoft.Xna.Framework;

namespace Sublimation
{
    public class GeneralManipulator: GameComponent
    {
        protected WorldPropertiesSurf worldProperties;
        protected List<Contact> addedContacts;
        protected List<Contact> previousContacts;
        protected GameObject owner;

        #region ManipulationProperties

        protected Affine2DManipulationProcessor manipulationProcessor;
        public Affine2DManipulationProcessor ManipulationProcessor
        {
            get
            {
                return manipulationProcessor;
            }
        }
        protected bool isManipulating;
        protected float manipulationXPoint = 0.0f;
        public float ManipulationXPoint
        {
            get
            {
                return manipulationXPoint;
            }
        }
        protected float manipulationYPoint = 0.0f;
        public float ManipulationYPoint
        {
            get
            {
                return manipulationYPoint;
            }
        }
        protected float manipulationScale = 1.0f;
        public float ManipulationScale
        {
            get
            {
                return manipulationScale;
            }
        }
        protected float manipulationRotation = 0.0f;
        public float ManipulationRotation
        {
            get
            {
                return manipulationRotation;
            }
        }

        #endregion

        #region ManipulationEvents
        private void OnAffine2DManipulationStarted(object sender, Affine2DOperationStartedEventArgs e)
        {
            isManipulating = true;
        }

        private void OnAffine2DManipulationCompleted(object sender, Affine2DOperationCompletedEventArgs e)
        {
            isManipulating = false;
        }

        private void OnAffine2DDelta(object sender, Affine2DOperationDeltaEventArgs e)
        {
            // Validate the state.
            //Debug.Assert((this.isManipulating && sender is Affine2DManipulationProcessor));

            // Update manipulation values.
            this.manipulationXPoint += e.DeltaX;
            this.manipulationYPoint += e.DeltaY;
            this.manipulationScale *= e.ScaleDelta;
            this.manipulationRotation += e.RotationDelta;
        }
        #endregion

        #region InitManipulationProcessor
        public void init(bool can_transX, bool can_transY, bool can_Rotate, bool can_Scale)
        {
            Affine2DManipulations supportedManipulations = Affine2DManipulations.None;
            if (can_transX)
            {
                supportedManipulations |= Affine2DManipulations.TranslateX;
            }
            if (can_transY)
            {
                supportedManipulations |= Affine2DManipulations.TranslateY;
            }
            if (can_Rotate)
            {
                supportedManipulations |= Affine2DManipulations.Rotate;
            }
            if (can_Scale)
            {
                supportedManipulations |= Affine2DManipulations.Scale;
            }
            
            // Create and initialize the manipulation processor with the supported manipulations.
            manipulationProcessor = new Affine2DManipulationProcessor(supportedManipulations);

            // Add handlers for manipulation events.
            manipulationProcessor.Affine2DManipulationStarted +=
                new EventHandler<Affine2DOperationStartedEventArgs>(OnAffine2DManipulationStarted);
            manipulationProcessor.Affine2DManipulationCompleted +=
                new EventHandler<Affine2DOperationCompletedEventArgs>(OnAffine2DManipulationCompleted);
            manipulationProcessor.Affine2DManipulationDelta +=
                new EventHandler<Affine2DOperationDeltaEventArgs>(OnAffine2DDelta);
            
        }
        #endregion

        public GeneralManipulator(Game game, float manipulationXPoint, float manipulationYPoint, float manipulationScale, float manipulationRotation,GameObject owner, bool can_transX, bool can_transY, bool can_Rotate, bool can_Scale)
        :base(game){
            this.owner = owner ;
            game.Components.Add(this);
            init(can_transX, can_transY, can_Rotate, can_Scale);
            this.manipulationXPoint = manipulationXPoint;
            this.manipulationYPoint = manipulationYPoint;
            this.manipulationScale = manipulationScale;
            this.manipulationRotation = manipulationRotation;
        }

        public void add_contact(Contact contact)
        {
            if (!addedContacts.Contains(contact))
            {
                addedContacts.Add(contact);
            }
        }

        public void remove_contact(Contact contact)
        {
            if (addedContacts.Contains(contact))
            {
                addedContacts.Remove(contact);
            }
        }
    }

}
